<template>
    <div class="img-transform-shadow">
        <input
            type="file"
            name="img"
            id="img"
            accept="image/*"
            @change="changeImg"
        />
        <img
            v-if="imgSrc"
            ref="imgRef"
            :src="imgSrc"
            alt="图片"
            class="its-img"
        />
        <SyncOutlined
            v-if="loading"
            spin
            style="
                display: flex;
                justify-content: center;
                align-items: center;
                width: 600px;
                height: 600px;
                font-size: 80px;
            "
        />
        <div
            v-show="!loading"
            class="its-div"
            :style="{ boxShadow: shadow }"
        ></div>
    </div>
</template>
<script setup lang="ts">
import { SyncOutlined } from '@ant-design/icons-vue'
import { nextTick, ref } from 'vue'
const shadow = ref('')
const imgSrc = ref('')
const loading = ref(false)
const imgData = new Image()
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
const pxData: string[] = []
const setBoxShadow = () => {
    console.log('setBoxShadow')
    pxData.length = 0
    const width = 500
    const height = (imgData.naturalHeight / imgData.naturalWidth) * width

    canvas.width = width
    canvas.height = height
    ctx?.clearRect(0, 0, width, height)
    ctx?.drawImage(imgData, 0, 0, width, height)
    const imageData = ctx?.getImageData(0, 0, width, height)
    for (let i = 0; i < (imageData?.data || []).length; i = i + 4) {
        const index = Math.floor(i / 4)
        const floor = Math.floor(index / width)
        pxData.push(
            `${index % width}px ${floor}px 1px 1px rgba(${
                imageData?.data[i] || 0
            }, ${imageData?.data[i + 1] || 0}, ${
                imageData?.data[i + 2] || 0
            }, ${imageData?.data[i + 3] || 0})`
        )
    }
    shadow.value = pxData.join(',')
    nextTick(() => {
        loading.value = false
    })
}
imgData.addEventListener('load', setBoxShadow)
const changeImg = (e: Event) => {
    loading.value = true
    const file = e.target?.files[0]
    if (file && file instanceof Blob) {
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => {
            imgSrc.value = reader.result as string
            imgData.src = reader.result as string
        }
    }
}
</script>
<style lang="scss" scoped>
.img-transform-shadow {
    display: flex;
    .its-img {
        width: 500px;
        margin-right: 10px;
    }
    .its-div {
        width: 1px;
        height: 1px;
    }
}
</style>
